home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Inside!
/
Amiga FD Inside (1995)(Ultramax).iso
/
berndspd
/
systemtools
/
appcon
/
src
/
appcon.c
next >
Wrap
C/C++ Source or Header
|
1994-05-14
|
15KB
|
593 lines
/* AppCon Main Source
**
** Done by Stephan Fuhrmann
**
*/
#define MTYPE_APPWINDOW 7
#define EXEC_MINIMUM 36
#define MY_ID 3111973
/*#define DEBUG_ME*/
#include <AppCon.h>
#include <dos.h>
//#include <stdio.h>
//#include <stdlib.h>
#define FILENAME_MAX 128
#include <string.h>
#include <dos/dos.h>
#include <dos/dosextens.h>
#include <exec/execbase.h>
#include <exec/ports.h>
#include <exec/io.h>
#include <exec/libraries.h>
#include <exec/memory.h>
#include <exec/interrupts.h>
#include <exec/tasks.h>
#include <devices/console.h>
#include <devices/conunit.h>
#include <devices/keymap.h>
#include <devices/input.h>
#include <devices/inputevent.h>
#include <devices/timer.h>
#include <intuition/intuition.h>
#include <intuition/intuitionbase.h>
#include <workbench/startup.h>
#include <workbench/workbench.h>
#ifdef LATTICE
int CXBRK(void) { return(0); }
int chkabort(void) { return(0); }
#endif
struct ExecBase *SysBase;
struct IntuitionBase *IntuitionBase;
struct Library *WorkbenchBase;
struct Library *KeymapBase;
struct DosLibrary *DOSBase;
struct Library *UtilityBase;
#include <proto/exec.h>
#include <proto/dos.h>
#include <proto/intuition.h>
#include <proto/wb.h>
#include <proto/keymap.h>
#include <proto/utility.h>
long timeout=10; /* in tenths of a second */
const char vt[]=VERSTAG;
struct Process *AppConTask=0L;
struct CommandLineInterface *AppCLI;
struct Window *AppConWindow;
struct MsgPort *timeport=0L;
struct MsgPort *appport=0L;
struct MsgPort *ioreply=0L;
struct IOStdReq *iorequest=0L;
struct timerequest *timerio=0L;
struct AppWindow *AppWindow;
struct AppMessage *AppMessage;
struct InputEvent *InputEvent;
ULONG WaitSignals=SIGBREAKF_CTRL_C;
ULONG ReceivedSignals;
char filename[FILENAME_MAX];
char dirname[FILENAME_MAX];
char pathname[FILENAME_MAX*2];
char AppConName[]="AppCon";
#define TEMPLATE "TimeOut=Time/K/N"
enum templates {OPT_TIMEOUT,OPT_COUNT};
LONG opts[OPT_COUNT];
char HelpPage[]=
"\nAppCon Help\n"\
"-----------\n"\
"© 1994 Stephan Fuhrmann\n\n"\
"Options\n"\
"---------\n"\
"TIMEOUT...timeout between checks of window closing, in tenths of a second\\NUMBER\n"\
"\nExample: AppCon TIMEOUT=10\n";
int breakother (struct Process *MyProc);
struct InputEvent *SendEvents (struct IOStdReq *iorequest,struct InputEvent *SendUs);
void MakeActive (struct Window *ActivateMe);
struct InputEvent *BrewInputevent(char *ASCII);
void FreeIEs (struct InputEvent *firstie);
struct Window *GetConWindow (struct Process *ConProcess,struct MsgPort *MyPort);
long AntiBlocking (struct Window *MyWin);
void MegaAbort (struct IOStdReq *);
void LaunchRequest (long secs,long micros,struct timerequest *mytimerio);
__saveds int main(int argc,char *argv)
{
struct RDArgs *argsptr;
APTR oldname;
SysBase=*(struct ExecBase **)4;
AppConTask=(struct Process *) FindTask(NULL);
oldname=AppConTask->pr_Task.tc_Node.ln_Name;
AppConTask->pr_Task.tc_Node.ln_Name=AppConName;
if (!argc)
return (0);
if (DOSBase=(struct DosLibrary *)OpenLibrary ("dos.library",37))
{
PutStr (VSTRING);
PutStr ("PUBLIC DOMAIN written 1993/94 by Stephan Fuhrmann\n");
if (IntuitionBase=(struct IntuitionBase *)OpenLibrary ("intuition.library",37))
{
if (WorkbenchBase=OpenLibrary ("workbench.library",37))
{
if (KeymapBase=OpenLibrary ("keymap.library",37))
{
if (UtilityBase=OpenLibrary ("utility.library",37))
{
if (breakother (AppConTask))
{
argsptr=AllocDosObject (DOS_RDARGS,0);
if (argsptr)
{
argsptr->RDA_ExtHelp=HelpPage;
if (!ReadArgs (TEMPLATE,opts,argsptr))
{
PrintFault (IoErr(),NULL);
FreeArgs (argsptr);
FreeDosObject (DOS_RDARGS,argsptr);
return (0);
}
if (opts[OPT_TIMEOUT])
timeout=*(LONG *)opts[OPT_TIMEOUT];
if ((ioreply=CreateMsgPort()) && (appport=CreateMsgPort()) && (timeport=CreateMsgPort()))
{
appport->mp_Node.ln_Name=AppConName;
WaitSignals |= 1L << (ioreply->mp_SigBit);
WaitSignals |= 1L << (timeport->mp_SigBit);
WaitSignals |= 1L << (appport->mp_SigBit);
if ((iorequest=CreateIORequest(ioreply,sizeof(struct IOStdReq)))
&& (timerio=CreateIORequest(timeport,sizeof(struct timerequest))))
{
if (!OpenDevice ("timer.device",UNIT_VBLANK,(struct IORequest *)timerio,0))
{
if (!OpenDevice ("input.device",0L,(struct IORequest *)iorequest,0))
{
AppConWindow=GetConWindow (AppConTask,ioreply);
if (AppConWindow)
{
if (AppWindow=AddAppWindowA (MY_ID,NULL,AppConWindow,appport,NULL))
{
ReceivedSignals=0;
LaunchRequest (timeout / 10,(timeout % 10) * 100000,timerio);
while (!(ReceivedSignals & SIGBREAKF_CTRL_C))
{
ReceivedSignals=Wait (WaitSignals);
if (ReceivedSignals & (1L << (timeport->mp_SigBit)))
{
ReceivedSignals &= ~ (1L << (timeport->mp_SigBit));
MegaAbort ((struct IOStdReq *)timerio);
LaunchRequest (timeout / 10,(timeout % 10) * 100000,timerio);
if (AntiBlocking (AppConTask->pr_ConsoleTask) <= 1)
Signal ((struct Task *)AppConTask,SIGBREAKF_CTRL_C);
}
if (ReceivedSignals & (1L << (appport->mp_SigBit)))
{
ReceivedSignals &= ~ (1L << (appport->mp_SigBit));
while (AppMessage = (struct AppMessage *)GetMsg (appport))
{
register long cnt,max;
register struct WBArg *curarg;
struct WBArg *argptr;
if ((AppMessage->am_Type)!=MTYPE_APPWINDOW)
{
#ifdef DEBUG_ME
VPrintf ("Unknown type (%ld)!",&AppMessage->am_Type);
#endif
ReplyMsg((struct Message *)AppMessage);
continue;
}
max=AppMessage->am_NumArgs;
curarg=AppMessage->am_ArgList;
if (!max)
{
#ifdef DEBUG_ME
VPrintf ("Not enough arguments (%ld)!",&max);
#endif
ReplyMsg((struct Message *)AppMessage);
continue;
}
argptr=curarg;
for (cnt=0;cnt<max;cnt++)
{
int hasspace;
int plusend;
if (argptr->wa_Lock)
NameFromLock(argptr->wa_Lock,dirname,FILENAME_MAX);
strcpy (pathname,dirname);
if (argptr->wa_Name)
AddPart(pathname,argptr->wa_Name,FILENAME_MAX*2);
if (cnt)
{
if (InputEvent=BrewInputevent (" "))
{
MakeActive (AppConWindow);
FreeIEs(SendEvents (iorequest,InputEvent));
}
else
DisplayBeep(0);
}
hasspace=(int)strchr(pathname,' ');
plusend=*(pathname+strlen(pathname)-1)=='+';
if (hasspace || plusend)
{
if (InputEvent=BrewInputevent ("\""))
{
MakeActive (AppConWindow);
FreeIEs(SendEvents (iorequest,InputEvent));
}
else
DisplayBeep(0);
}
if (InputEvent=BrewInputevent (pathname))
{
MakeActive (AppConWindow);
FreeIEs (SendEvents (iorequest,InputEvent));
}
else
DisplayBeep (0);
if (hasspace || plusend)
{
if (InputEvent=BrewInputevent ("\""))
{
MakeActive (AppConWindow);
FreeIEs(SendEvents (iorequest,InputEvent));
}
else
DisplayBeep (0);
}
argptr++;
}
ReplyMsg((struct Message *)AppMessage);
}
}
}
RemoveAppWindow (AppWindow);
}
else
PutStr ("Couldn't add AppWindow\n");
}
else
PutStr ("Couldn't find console window!\n");
MegaAbort (iorequest);
CloseDevice ((struct IORequest *)iorequest);
}
else
PutStr ("Couldn't open console.device");
MegaAbort ((struct IOStdReq *)timerio);
CloseDevice ((struct IORequest *)timerio);
}
else
PutStr ("Couldn't open timer.device\n");
}
else
PutStr ("Couldn't create IORequest\n");
DeleteIORequest (timerio);
DeleteIORequest (iorequest);
}
else
PutStr ("Couldn't create msgport\n");
DeleteMsgPort (timeport);
DeleteMsgPort (ioreply);
DeleteMsgPort (appport);
}
else
PutStr ("Couldn't allocate ReadArgs-Object\n");
FreeArgs (argsptr);
if (argsptr)
FreeDosObject (DOS_RDARGS,argsptr);
}
else
PutStr ("Removed existing AppCon-Task.\n");
CloseLibrary (UtilityBase);
}
CloseLibrary (KeymapBase);
}
CloseLibrary (WorkbenchBase);
}
CloseLibrary ((struct Library *)IntuitionBase);
}
CloseLibrary ((struct Library *)DOSBase);
}
AppConTask->pr_Task.tc_Node.ln_Name=oldname;
return (0);
}
int breakother (struct Process *MyProc)
{
struct List *MyList;
struct Process *ProcPtr;
APTR MyConTask;
UWORD cnt;
int result=1;
/* critical sections start */
Forbid();
MyConTask=MyProc->pr_ConsoleTask;
for (cnt=0;cnt<2;cnt++)
{
MyList=cnt ? &SysBase->TaskReady : &SysBase->TaskWait;
for (ProcPtr=(struct Process *)MyList->lh_Head ;
ProcPtr->pr_Task.tc_Node.ln_Succ!=MyList->lh_Tail ;
ProcPtr=(struct Process *)ProcPtr->pr_Task.tc_Node.ln_Succ)
{
if (ProcPtr->pr_Task.tc_Node.ln_Type==NT_PROCESS)
{
if ((ProcPtr->pr_ConsoleTask==MyConTask) && (ProcPtr!=MyProc))
{
if (!strcmp(ProcPtr->pr_Task.tc_Node.ln_Name,AppConName))
{
Signal ((struct Task *)ProcPtr,SIGBREAKF_CTRL_C);
result=0;
}
}
}
}
}
Permit();
/* critical section end */
return (result);
}
struct InputEvent *SendEvents (struct IOStdReq *iorequest,struct InputEvent *SendUs)
{
struct InputEvent *ThisEvent,*NextEvent;
ThisEvent=SendUs;
while (ThisEvent)
{
iorequest->io_Command=IND_WRITEEVENT;
iorequest->io_Length=sizeof(struct InputEvent);
iorequest->io_Data=ThisEvent;
NextEvent=ThisEvent->ie_NextEvent;
ThisEvent->ie_NextEvent=0L;
__emit (0x48e7);
__emit (0xfffe);
DoIO ((struct IORequest *)iorequest);
__emit (0x4cdf);
__emit (0x7fff);
ThisEvent->ie_NextEvent=NextEvent; /* recover NextEvent-field for later FreeMem-stuff */
ThisEvent=NextEvent;
}
return (SendUs);
}
void MakeActive (struct Window *ActivateMe)
{
if (! ((ActivateMe->Flags) & WFLG_WINDOWACTIVE))
{
ActivateWindow (ActivateMe);
while (! ((ActivateMe->Flags) & WFLG_WINDOWACTIVE))
Delay (1);
}
}
void FreeIEs (struct InputEvent *firstie)
{
register struct InputEvent *nextie;
while (firstie)
{
nextie=firstie->ie_NextEvent;
FreeMem (firstie,sizeof (struct InputEvent));
firstie=nextie;
}
}
struct InputEvent *BrewInputevent(char *ASCII)
{
struct InputEvent *thisie,*oldie,*grandpa,*firstie;
register long cnt;
long junksize;
WORD *junkbuf;
long rawsize;
firstie=0;
thisie=0;
oldie=0;
junksize=strlen(ASCII)*3;
if (!(junkbuf=AllocVec(junksize*sizeof(WORD),MEMF_CLEAR|MEMF_PUBLIC)))
return (0);
rawsize=MapANSI (ASCII,strlen(ASCII),(STRPTR)junkbuf,junksize,0);
switch (rawsize)
{
case 0:
case -1:
case -2:
FreeVec (junkbuf);
return (0);
}
for (cnt=0;cnt<rawsize;cnt++)
{
grandpa=oldie;
oldie=thisie;
thisie=AllocMem(sizeof (struct InputEvent),MEMF_CLEAR|MEMF_PUBLIC);
if (!thisie)
{
FreeVec (junkbuf);
FreeIEs(firstie);
return (0);
}
if (oldie)
oldie->ie_NextEvent=thisie;
else
firstie=thisie;
/* PARANOIA! */
//thisie->ie_NextEvent=0;
thisie->ie_Class=IECLASS_RAWKEY;
//thisie->ie_SubClass=0;
thisie->ie_Code=(*(junkbuf+cnt)>>8) & 255;
thisie->ie_Qualifier=*(junkbuf+cnt) & 255;
if (oldie)
{
thisie->ie_position.ie_dead.ie_prev1DownCode=oldie->ie_Code;
thisie->ie_position.ie_dead.ie_prev1DownQual=oldie->ie_Qualifier;
}
if (grandpa)
{
thisie->ie_position.ie_dead.ie_prev2DownCode=grandpa->ie_Code;
thisie->ie_position.ie_dead.ie_prev2DownQual=grandpa->ie_Qualifier;
}
}
FreeVec (junkbuf);
return (firstie);
}
struct Window *GetConWindow (struct Process *ConProcess,struct MsgPort *MyPort)
{
struct Window *ResultWindow;
struct MsgPort *con;
struct StandardPacket packet;
struct InfoData id;
ResultWindow=0L;
if (ConProcess->pr_Task.tc_Node.ln_Type == NT_PROCESS)
{
con=ConProcess->pr_ConsoleTask;
if (con)
{
packet.sp_Msg.mn_Node.ln_Name=(char *)&(packet.sp_Pkt);
packet.sp_Pkt.dp_Link=&(packet.sp_Msg);
packet.sp_Pkt.dp_Port=MyPort;
packet.sp_Pkt.dp_Type=ACTION_DISK_INFO;
packet.sp_Pkt.dp_Arg1=((ULONG) &id) >> 2;
PutMsg (con,(struct Message *)&packet);
WaitPort (MyPort);
ResultWindow=(struct Window *)id.id_VolumeNode;
}
}
return (ResultWindow);
}
long AntiBlocking (APTR MyConsoleTask)
{
long winusers=0;
long cnt,max;
Forbid();
max=MaxCli()+1;
for (cnt=1;cnt < max;cnt++)
{
struct Process *ThisProc;
if (ThisProc=FindCliProc (cnt))
{
if (ThisProc->pr_ConsoleTask == MyConsoleTask)
winusers++;
}
}
Permit();
return (winusers);
}
void MegaAbort (struct IOStdReq *AbortMe)
{
AbortIO ((struct IORequest *)AbortMe);
WaitIO ((struct IORequest *)AbortMe);
SetSignal (0L,1L << (AbortMe->io_Message.mn_ReplyPort->mp_SigBit));
}
void LaunchRequest (long secs,long micros,struct timerequest *mytimerio)
{
timerio->tr_node.io_Command=TR_ADDREQUEST;
timerio->tr_time.tv_secs=secs;
timerio->tr_time.tv_micro=micros;
SendIO ((struct IORequest *)mytimerio);
}